package com.cxyd.handler;

import cn.hutool.core.util.StrUtil;
import com.cxyd.common.ClientConstants;
import com.cxyd.service.PlcItemService;
import com.cxyd.utils.SpringUtils;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;

import java.net.InetSocketAddress;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
public class TransferHandler extends ChannelInboundHandlerAdapter {
    private final AtomicInteger currentState;
    private final Runnable disconnectCallback;
    private final String message;
    private final PlcItemService itemService = SpringUtils.getBean("plcItemServiceImpl");

    public TransferHandler(AtomicInteger currentState, Runnable disconnectCallback, String message) {
        this.currentState = currentState;
        this.disconnectCallback = disconnectCallback;
        this.message = message;
    }

    /**
     * 读取来自服务端的消息
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //接收到PLC端的原始回复报文
//        log.info("接收到的值为:{}", msg);
//        解析报文并翻译写入PLC_ITEM表中（0506050002000000）
        itemService.scanHandler(getRemoteAddress(ctx), StrUtil.toString(msg));
    }

    /**
     * 当channel准备就绪时可向服务端发送消息
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        //连接成功,将ChannelHandlerContext添加至共享Map中后续使用
//        ShareStaticMap.clientContext.put(getRemoteAddress(ctx), ctx);
        currentState.set(ClientConstants.CLIENT_STATUS_STARTED);
        log.info("[ClientHandler] handler active, remote address: {" + getRemoteAddress(ctx) + "}");
        //定时访问状态(5s/次)
        ctx.channel().eventLoop().scheduleWithFixedDelay(() -> {
            if (currentState.get() == ClientConstants.CLIENT_STATUS_STARTED && message != "") {
                ctx.writeAndFlush(message);
//                log.info("成功发送消息:{}", message);
            }
        }, 0, 3, TimeUnit.SECONDS);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("[ClientHandler] handler inactive, remote address: {" + getRemoteAddress(ctx) + "}");
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        log.info("[ClientHandler] channel unregistered, remote address:{" + getRemoteAddress(ctx) + "}");
        currentState.set(ClientConstants.CLIENT_STATUS_OFF);
        //断开连接,将ChannelHandlerContext从共享Map中移除
//        ShareStaticMap.clientContext.remove(getRemoteAddress(ctx));
        disconnectCallback.run();
    }

    /**
     * 获取异常
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("[ClientHandler] exception：" + cause);
    }

    private String getRemoteAddress(ChannelHandlerContext ctx) {
        if (ctx.channel().remoteAddress() == null) {
            return null;
        }
        InetSocketAddress inetAddress = (InetSocketAddress) ctx.channel().remoteAddress();
        return inetAddress.getAddress().getHostAddress();
    }

    public int getCurrentState() {
        return currentState.get();
    }

    public boolean hasStarted() {
        return getCurrentState() == ClientConstants.CLIENT_STATUS_STARTED;
    }
}
